using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace Ideopuzzle.Effects
{
    public enum ExplosionType
    { 
        Normal,
        Short
    }

    public class ExplosionComponent : Microsoft.Xna.Framework.DrawableGameComponent
    {
        private static readonly int EXPLOSION_TILES_N = 20;
        private static readonly int TILE_WIDTH = 86;
        private static readonly int TILE_HEIGHT = 121;

        Texture2D explosion_tiles;
        SpriteBatch sprite_batch;
        List<ExplosionInfo> explosions;
        List<Rectangle> tiles_rect;

        public ExplosionComponent(Game game)
            : base(game)
        {
            explosions = new List<ExplosionInfo>();
            tiles_rect = new List<Rectangle>();

            DrawOrder = 100;
        }

        public override void Initialize()
        {

            base.Initialize();
        }

        protected override void LoadContent()
        {
            sprite_batch = Game.Services.GetService(typeof(SpriteBatch)) as SpriteBatch;

            explosion_tiles = Game.Content.Load<Texture2D>("Textures/Game/explo");

            for (int i = 0; i < EXPLOSION_TILES_N; i++)
            {
                tiles_rect.Add(new Rectangle(TILE_WIDTH * i,0,TILE_WIDTH, TILE_HEIGHT));
            }

            base.LoadContent();
        }

        public override void Update(GameTime gameTime)
        {
            for (int i = 0; i < explosions.Count; i++)
            {
                explosions[i].timer += (float)gameTime.ElapsedGameTime.TotalSeconds;

                if (explosions[i].timer > explosions[i].duration)
                {
                    explosions.RemoveAt(i);
                    i--;
                }
            }

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            sprite_batch.Begin();

            for (int i = 0; i < explosions.Count; i++)
            {
                sprite_batch.Draw(explosion_tiles, explosions[i].rect, 
                    tiles_rect[Math.Min(EXPLOSION_TILES_N, (int)(EXPLOSION_TILES_N * explosions[i].timer / explosions[i].duration))], 
                    Color.White);
            }

            sprite_batch.End();

            base.Draw(gameTime);
        }

        public void AddExplosion(Vector2 position, ExplosionType type)
        {
            switch (type)
            { 
                case ExplosionType.Normal:
                    explosions.Add(new ExplosionInfo(position, 1.0f));
                    break;
                default:
                    explosions.Add(new ExplosionInfo(position, 0.5f));
                    break;
            }
        }

        public class ExplosionInfo
        {
            public Rectangle rect;
            public Vector2 position;
            public float timer;
            public float duration;

            public ExplosionInfo(Vector2 position, float duration)
            {
                this.position = position;
                this.duration = duration;

                var x = (int)(position.X + GameBoard.CELL_DIM / 2.0f - TILE_WIDTH / 2.0f);
                var y = (int)(position.Y + GameBoard.CELL_DIM / 2.0f - TILE_HEIGHT / 2.0f);

                this.rect = new Rectangle(x, y, TILE_WIDTH, TILE_HEIGHT);
            }
        }
    }
}
